-------------------------------------------------------------------------------
-- Archivo: 			         hazard_fsm.vhdl
-- Fecha de creación:            25/01/2011
-- Última fecha de modificación: 28/01/2011
-- Diseñador: 			         Cesar A. Fuguet T.
-- Diseño: 			             hazard_fsm
-- Propósito: 			         Máquina de estados para inhabilitar la captura
--                               de instrucción en caso de dependencia.
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

entity hazard_fsm is
  
    port (
        COUNTER_i    : in  std_logic_vector(1 downto 0);
        HAZARD_i     : in  std_logic;
        CLK_i        : in  std_logic;
        RESET_i      : in  std_logic;
        OPCODE_i     : in  std_logic_vector(3 downto 0);
        FFT_STG_i    : in  std_logic_vector(2 downto 0);
        HAZARD_FSM_o : out std_logic;
        HAZARD_NXT_o : out std_logic);

end hazard_fsm;

architecture fsm of hazard_fsm is
    constant FFT_OPCODE : std_logic_vector(3 downto 0) := "1111";
    constant FFT_STAGE3 : std_logic_vector(2 downto 0) := "011";

    constant HAZARD_STATE0 : std_logic := '0';
    constant HAZARD_STATE1 : std_logic := '1';

    signal curr_state : std_logic;
    signal next_state : std_logic;

  
begin  -- fsm

-- next_state <= '1'
-- when ((COUNTER_i = "11" and HAZARD_i = '1'
-- and curr_state = HAZARD_STATE0)
-- and (OPCODE_i /= FFT_OPCODE or FFT_STG_i = FFT_STAGE3)) else
-- '0' when (COUNTER_i = "11" and curr_state = HAZARD_STATE1) else
-- curr_state;

    next_state <= 
        HAZARD_STATE1
            when (curr_state = HAZARD_STATE0 and COUNTER_i = "11"
                  and (HAZARD_i = '1' or OPCODE_i = FFT_OPCODE)) else

        HAZARD_STATE0
            when (curr_state = HAZARD_STATE1 and COUNTER_i = "11"
                  and (OPCODE_i /= FFT_OPCODE or FFT_STG_i = FFT_STAGE3 ))

        else curr_state;
                

    dep_sm: process (CLK_i, RESET_i)
    begin      
    if CLK_i'event and CLK_i = '1' then  -- rising clock edge
        if RESET_i = '1' then
            curr_state <= '0';
        else
            curr_state <= next_state;
        end if;
    end if;
    end process dep_sm;  

    HAZARD_FSM_o <= curr_state;
    HAZARD_NXT_o <= next_state;
  
end fsm;

-- vim: tabstop=4 : expandtab : shiftwidth=4
